﻿using Microsoft.EntityFrameworkCore;
using PLCS.Domain.Tasks;
using PLCS.EntityFrameworkCore.EntityFrameworkCore;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace PLCS.EntityFrameworkCore.Tasks;

public class TaskRepository : EfCoreRepository<PLCSDbContext, TaskModel, Guid>, ITaskRepository
{
    public TaskRepository(IDbContextProvider<PLCSDbContext> dbContextProvider) : base(dbContextProvider)
    {
    }

    public override async Task<TaskModel> GetAsync(Guid id, bool includeDetails = true, CancellationToken cancellationToken = default)
    {
        var query = await WithDetailsAsync(x => x.Instructions);
        query = query.Where(x => x.Id == id);
        var task = await AsyncExecuter.SingleOrDefaultAsync(query);
        return task;
    }

    public async Task ChangeStatusAsync(Guid Id, Domain.Shared.Tasks.TaskStatus taskStatus)
    {
        var dbContext = await GetDbContextAsync();

        var task = await dbContext.Tasks.Where(x => x.Id == Id).FirstOrDefaultAsync();
        Check.NotNull(task, Id.ToString(), $"不存在任务:{Id}");
        task.ChangeStatus(taskStatus);
        await dbContext.SaveChangesAsync();
    }

    public async Task<TaskModel?> GetByTaskIdAsync(int taskId)
    {
        var query = await WithDetailsAsync(x => x.Instructions);
        query = query.Where(x => x.TaskId == taskId);
        var task = await AsyncExecuter.SingleOrDefaultAsync(query);
        return task;
    }

    public async Task<TaskModel> GetLastTaskAsync()
    {
        var query = await WithDetailsAsync(x => x.Instructions);
        query = query.OrderByDescending(x => x.TaskId);
        var task = await AsyncExecuter.FirstOrDefaultAsync(query);
        return task;
    }

    public async Task<IEnumerable<TaskModel>> GetListWithDetailsAsync()
    {
        var querable = await WithDetailsAsync(i => i.Instructions.OrderBy(x => x.InstructionNo));
        querable = querable.OrderByDescending(x => x.TaskId);
        return await AsyncExecuter.ToListAsync(querable);
    }

    public async Task<IEnumerable<TaskModel>> GetUnfinshedTaskAsync()
    {
        var taskQueryable = await GetQueryableAsync();
        taskQueryable = taskQueryable.Where(x => x.TaskStatus == Domain.Shared.Tasks.TaskStatus.未执行)
                     .OrderByDescending(x => x.Level);
        return await taskQueryable.ToListAsync();
    }

    public async Task<IEnumerable<TaskModel>> GetUnfinshedAboutRunningTaskAsync()
    {
        var taskQueryable = await GetQueryableAsync();
        taskQueryable = taskQueryable.Where(x => x.TaskStatus == Domain.Shared.Tasks.TaskStatus.未执行 || x.TaskStatus == Domain.Shared.Tasks.TaskStatus.执行中 || x.TaskStatus == Domain.Shared.Tasks.TaskStatus.解析完成)
                     .OrderByDescending(x => x.Level);
        return await taskQueryable.ToListAsync();
    }

    public async Task HardDeleteAsync(Guid Id)
    {
        var dbContext = await GetDbContextAsync();
        await dbContext.Database.ExecuteSqlRawAsync($"DELETE FROM T_Instructions WHERE TaskId = '{Id}'");
        await dbContext.Database.ExecuteSqlRawAsync($"DELETE FROM T_Tasks WHERE Id = '{Id}'");
    }
}